﻿Imports OpenTK
Imports OpenTK.Graphics
Imports OpenTK.Graphics.OpenGL4

Class TriangleReflectionRegion
    Inherits ShaderBase

    Dim triangles() As Single
    Protected cshader As Integer
    Public Sub New(triangledata() As Single)
        triangles = triangledata
        program = GL.CreateProgram()
        cshader = GL.CreateShader(ShaderType.ComputeShader)
        GL.ShaderSource(cshader, System.IO.File.ReadAllText("shader\TriangleRegionDivision.glcs"))
        GL.CompileShader(cshader)
        Dim csLog As String = GL.GetShaderInfoLog(cshader)
        Console.WriteLine(csLog)
        If csLog.Contains("error") Then Throw New Exception(csLog)
        GL.AttachShader(program, cshader)
        GL.LinkProgram(program)
        Dim programLog As String = GL.GetProgramInfoLog(program)
        Console.WriteLine(programLog)
        If programLog.Contains("error") Then Throw New Exception(programLog)
    End Sub

    Public img As Integer
    Private triangleCount As Integer
    Dim outTex() As Single
    Public Sub InitImage(nTriangle As Integer)
        'allocate
        triangleCount = nTriangle
        img = GL.GenTexture()
        GL.BindTexture(TextureTarget.Texture2D, img)
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureMagFilter.Nearest)
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureMinFilter.Nearest)
        'GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32f, nTriangle, nTriangle, 0, PixelFormat.Rgba, PixelType.Float, outTex)
        GL.TexStorage2D(TextureTarget2d.Texture2D, 1, SizedInternalFormat.R32f, nTriangle, nTriangle) ' levels should be greater than 0. different form TexImage2D's level parameter
        GL.BindTexture(TextureTarget.Texture2D, 0)
    End Sub

    Public Sub DispatchCompute(texTriangle As Integer)
        'bind input
        GL.UseProgram(program)
        Dim uInputTriangle = GL.GetUniformLocation(program, "inputTriangle")
        GL.ActiveTexture(TextureUnit.Texture0)
        GL.BindTexture(TextureTarget.Texture2D, texTriangle)
        GL.Uniform1(uInputTriangle, 0)

        Dim uTriangleCount = GL.GetUniformLocation(program, "TriangleCount")

        GL.Uniform1(uTriangleCount, triangleCount)
        GL.BindImageTexture(0, img, 0, False, 0, TextureAccess.ReadWrite, SizedInternalFormat.R32f)

        'compute
        GL.DispatchCompute(triangleCount, 1, 1)
        GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit)
        GL.Flush()

        'get result
        outTex = New Single(triangleCount * triangleCount - 1) {}
        GL.BindTexture(TextureTarget.Texture2D, img)
        GL.GetTexImage(TextureTarget.Texture2D, 0, PixelFormat.Red, PixelType.Float, outTex)
        Dim arr(triangleCount - 1) As List(Of Single)
        Dim max As Integer = 0
        For i = 0 To triangleCount - 1
            Dim size = outTex(i)
            arr(i) = New List(Of Single)
            For j = 0 To size - 1
                arr(i).Add(outTex((j + 1) * triangleCount + i))
            Next
            If size > max Then max = size
        Next
    End Sub

End Class
